package com.wlyuan.open.scanner.application.factory;

import com.wlyuan.open.scanner.application.annotation.TableScannerName;
import com.wlyuan.open.scanner.application.handler.table.BaseTableToIncrHandler;
import com.wlyuan.open.scanner.constant.TableEnum;
import com.wlyuan.open.scanner.exception.ValueErrorException;
import lombok.var;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author lijing
 * @description
 */
public final class TableNameHandlerFactory {

    /**
     * 增量同步table对应扫描名称
     */
    private static BaseTableToIncrHandler defaultScannerNameHandler = null;
    private static Map<String, BaseTableToIncrHandler> splitStreamScannerNameHandler = new ConcurrentHashMap<>();

    public static BaseTableToIncrHandler getTableHandler(String tableName) {
        if (splitStreamScannerNameHandler.containsKey(tableName)) {
            return splitStreamScannerNameHandler.get(tableName);
        }
        return defaultScannerNameHandler;
    }

    public static synchronized void initHandlers(Collection<BaseTableToIncrHandler> handlers) {
        Optional.ofNullable(handlers).ifPresent(
                hs -> {
                    hs.forEach(h -> {
                        Optional.ofNullable(h.getClass().getAnnotation(TableScannerName.class)).ifPresent(an -> {
                            boolean isDefault = an.isDefault();
                            if (isDefault && defaultScannerNameHandler != null) {
                                throw new ValueErrorException("the count of table scanner name in handler cannot be greater than 1 ");
                            }
                            if (isDefault) {
                                defaultScannerNameHandler = h;
                                return;
                            }
                            var list = parseTable(an.tableName()).stream().filter(x -> x != TableEnum.DEFAULT).collect(Collectors.toList());
                            list.forEach(table -> splitStreamScannerNameHandler.put(table.getVal(), h));
                        });
                    });
                }
        );
    }

    private static List<TableEnum> parseTable(TableEnum[] table) {
        if (Objects.nonNull(table) && table.length > 0) {
            return Arrays.stream(table).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

}
